package lexicalUnit;

import java.util.HashMap;

import aswerGenerator.AnsGenerator;
import aswerGenerator.EmptyQueryException;
import aswerGenerator.NotFoundInDatabaseException;
import chalmersbot.Absyn.ManyWord;
import chalmersbot.Absyn.ManyWrd;
import chalmersbot.Absyn.QWHowMany;
import chalmersbot.Absyn.Sentence;

/**
 * Class to store and process lexical information from a sentence
 * @author roijoris
 *
 */
public class Environ {
	//target keywords
	public static final int PLACE = 0;
	public static final int PERSON = 1;
	public static final int THING = 2;
	public static final int COURSE = 3;
	public static final int ROOM = 4;
	public static final int PERIOD = 5;
	public static final int PROGRAM = 6;
	public static final int YN_QUESTION = 7;
	public static final int BUILDING = 8;
	public static final int MANDATORY_COURSE = 9;
	public static final int OPTIONAL_COURSE = 10;
	public static final int CREDIT = 11;
	public static final int CODE = 12;
	public static final int CAMPUS = 13;
	public static final int COUNT = 14;
	public static final int LEVEL = 15;
	
	//lexical flags
	public static final int SUBJECT = 100;
	public static final int COMPLEMENT =101;
	public static final int THRID_PERSON = 103;
	public static final int PAST_TENSE = 104;
	public static final int PRESENT_TENSE = 104;
	public static final int FUTURE_TENSE = 105;
	
	public static final int GET_MAIN_VERB = 1000;
	public static final int AUX_VERB = 1001;
	public static final int ISVERB_TENSE = 1002;
	public static final int WHO_ANSWER = 1003;
	public static final int GENERIC_ANSWER = 1004;
	public static final int INWHICH_ANSWER = 1005;
	public static final int INHOW_ANSWER = 1006;
	public static final int FOLLOWING_ANSWER = 1007;
	
	//verb information
	public static final int VERB_TEACH = 10000;
	public static final int VERB_IS = 10001;
	
	
	//Program memory
	private static String lastTeacher;
	private static String lastRoom;
	private static String lastBuilding;
	private static String lastCourse;
	private static String lastCode;
	private static String lastPeriod;
	private static String lastProgram;
	private static String lastCampus;
	private static String other;
	private static String lastKeyWord;
	private static int lastKeywordClass = -1;
	
	//Temporal lexical information
	private int flag = SUBJECT;
	private String res = "";
	private String subject = null;
	private String verb = null;
	private String period = null;
	private String program = null;
	private boolean isPlural = false;
	private int numberOfAnswers = -1;
	private int kind_of_answer = -1;
	private HashMap<String,String> plurals= new HashMap<String,String>();
	private HashMap<String,String> singular= new HashMap<String,String>();
	private HashMap<String,String> thirPers= new HashMap<String,String>();
	private HashMap<String,String> past= new HashMap<String,String>();
	private int verbTense = -1;
	
	//temporal
	private int target = -1;
	private String keyword;
	private int keywordClass = -1;	
	private String ynkeyword = null;
	private int verbKeyword = -1;
	private String error = null;
	
	public void setInfo (){
		setLastKeyWord(keyword);
		switch (keywordClass){
		 case PERSON:
			 setLastTeacher(keyword);
			 break;
		 case COURSE:
			 setLastCourse(keyword);
			 break;
		 case ROOM:
			 setLastRoom(keyword);
			 break;
		 case PERIOD:
			 setLastPeriod(keyword);
			 break;
		 case PROGRAM: 
			 setLastProgram(keyword);
			 break;
		 case BUILDING:
			 setLastBuilding(keyword);
			 break;
		 case CODE:
			 setLastCode(keyword);
			 break;
		 case CAMPUS:
			 setLastCampus(keyword);
			 break;
		 default:
			 setOther(keyword);
			 break;
		 }
	}
	
	public String generateAnswer () {
		String ans = "";
		try {
			 if (target==PLACE || target==PERIOD)
				 ans = " in ";
			 ans = ans + new AnsGenerator(this).generateAnswerInfo();
			 setInfo ();
		} catch (EmptyQueryException e) {
			error = e.getMessage();
			return "";			
		} catch (NotFoundInDatabaseException e) {
			error = e.getMessage();
			return "";			
		}
		return ans;
	}
	
	public String getAnswer(Sentence s){
		String sentence = s.accept(new CheckSentence(), this);
		if (error==null)
			return sentence; 
		return error;
	}
	
	public static boolean isPlural(String subject) {
		if (subject.endsWith("s"))
			return true;
		return false;
	}
	
	public String toVerbTense (String verb){
		String answer = null;
		if (verbTense == Environ.THRID_PERSON)
			answer = thirPers.get(verb);
		if (verbTense == Environ.PAST_TENSE)
			answer = past.get(verb);
		if (answer!=null)
			return answer;
		return verb;
	}
	
	private String toSing (String word){
		if (singular.containsKey(word))
			return singular.get(word);
		return word;
	}
	
	private String toPlur (String word){
		if (plurals.containsKey(word))
			return plurals.get(word);
		return word;
	}
	
	public String toSingular (String word){
		String sentence = "";
		String[] result = word.split("\\s");
	    for (int x=0; x<result.length; x++)
	    	sentence = sentence + toSing(result[x]) + " ";
	    sentence.substring(0, sentence.length());
	    return sentence;
	}
	
	public String toPlural (String word){
		String sentence = "";
		String[] result = word.split("\\s");
	    for (int x=0; x<result.length; x++)
	    	sentence = sentence + toPlur(result[x]) + " ";
	    sentence.substring(0, sentence.length());
	    if (sentence.contains("codes") && sentence.contains("courses"))
	    	if (sentence.indexOf("codes")>sentence.indexOf("courses"))
	    		sentence = sentence.replace("courses", "course");
	    return sentence;
	}
	
	
	public String getSentence(){
		String answer = generateAnswer();
		if (getNumberOfAnswers()>1){
			subject = toPlural(subject);
			verb = toPlural(verb);
		}
		if (getNumberOfAnswers()==1){
			subject = toSingular(subject);
			verb = toSingular(verb);
		}
		if (kind_of_answer==WHO_ANSWER)
			return answer + " " + getVerb() + " " + getSubject();
		if (kind_of_answer==INWHICH_ANSWER)
			return "the " + getSubject() + " " + getVerb() + getRes() + " in " + answer;
		if (kind_of_answer==INHOW_ANSWER)
			return new QWHowMany("how", new ManyWord ("")).accept(new CheckQWHow(), this);
		if (kind_of_answer==FOLLOWING_ANSWER)
			return "the following " + getSubject() + " " + getVerb() + getRes() + ": " + answer;
		return subject + " " + verb + res + " "+ answer;
	}
	
	public void addToVerb (String newverb){
		if (verb==null)
			verb = newverb;
		else
			verb = verb + " " + newverb;
	}
	
	public int resetFlag (){
		int f = flag;
		flag = -1;
		return f;
	}
	
	//***************************************************************************************
	//Getters and setters
	
	public int getFlag() {
		return flag;
	}

	public int getTarget() {
		return target;
	}

	public void setTarget(int target) {
		this.target = target;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		if (this.keyword == null)
			this.keyword = keyword;
		else if (this.ynkeyword == null)
			ynkeyword = keyword;
	}

	public int getKeywordClass() {
		return keywordClass;
	}

	public void setKeywordClass(int keywordClass) {
		this.keywordClass = keywordClass;
	}

	public String getYnkeyword() {
		return ynkeyword;
	}

	public void setYnkeyword(String ynkeyword) {
		this.ynkeyword = ynkeyword;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	public String getRes() {
		return res;
	}

	public void setRes(String res) {
		this.res = " " + res;
	}

	public String getSubject() {
		return subject;
	}

	public void setSubject(String subject) {
		this.subject = subject;
		this.resetFlag();
	}

	public String getVerb() {
		return verb;
	}

	public void setVerb(String verb) {
		this.verb = verb;
	}
	
	public int getVerbTense() {
		return verbTense;
	}

	public void setVerbTense(int verbTense) {
		this.verbTense = verbTense;
	}

	public int getVerbKeyword() {
		return verbKeyword;
	}

	public void setVerbKeyword(int verbKeyword) {
		this.verbKeyword = verbKeyword;
	}

	public static String getLastTeacher() {
		return lastTeacher;
	}

	public static void setLastTeacher(String lastTeacher) {
		Environ.lastTeacher = lastTeacher;
	}

	public static String getLastRoom() {
		return lastRoom;
	}

	public static void setLastRoom(String lastRoom) {
		Environ.lastRoom = lastRoom;
	}

	public static String getLastBuilding() {
		return lastBuilding;
	}

	public static void setLastBuilding(String lastBuilding) {
		Environ.lastBuilding = lastBuilding;
	}

	public static String getLastCourse() {
		return lastCourse;
	}

	public static void setLastCourse(String lastCourse) {
		Environ.lastCourse = lastCourse;
	}

	public static String getLastCode() {
		return lastCode;
	}

	public static void setLastCode(String lastCode) {
		Environ.lastCode = lastCode;
	}

	public static String getLastPeriod() {
		return lastPeriod;
	}

	public static void setLastPeriod(String lastPeriod) {
		Environ.lastPeriod = lastPeriod;
	}

	public static String getLastProgram() {
		return lastProgram;
	}

	public static void setLastProgram(String lastProgram) {
		Environ.lastProgram = lastProgram;
	}

	public static String getLastCampus() {
		return lastCampus;
	}

	public static void setLastCampus(String lastCampus) {
		Environ.lastCampus = lastCampus;
	}

	public static String getOther() {
		return other;
	}

	public static void setOther(String other) {

	}

	public String getPeriod() {
		return period;
	}

	public void setPeriod(String period) {
		this.period = period;
	}

	public boolean isPlural() {
		return isPlural;
	}

	public void setPlural(boolean isPlural) {
		this.isPlural = isPlural;
	}

	public String getProgram() {
		return program;
	}

	public void setProgram(String program) {
		this.program = program;
	}

	public int getNumberOfAnswers() {
		return numberOfAnswers;
	}

	public void setNumberOfAnswers(int numberOfAnswers) {
		this.numberOfAnswers = numberOfAnswers;
	}

	public static String getLastKeyWord() {
		return lastKeyWord;
	}

	public static void setLastKeyWord(String lastKeyWord) {
		Environ.lastKeyWord = lastKeyWord;
	}

	public static int getLastKeywordClass() {
		return lastKeywordClass;
	}

	public static void setLastKeywordClass(int lastKeywordClass) {
		Environ.lastKeywordClass = lastKeywordClass;
	}
	
	public void setPlural(String key, String plural){
		this.plurals.put(key, plural);
	}
	
	public void setSingular(String key, String plural){
		this.singular.put(key, plural);
	}
	
	public void setThirdPers(String key, String thirPers){
		this.thirPers.put(key, thirPers);
	}
	
	public void setPast(String key, String past){
		this.past.put(key, past);
	}

	public int getKind_of_answer() {
		return kind_of_answer;
	}

	public void setKind_of_answer(int kind_of_answer) {
		this.kind_of_answer = kind_of_answer;
	}
}
